package com.czb.readcard;

import android.os.Bundle;
import android.os.RemoteException;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;

import com.czb.readcardlib.ReadM1Util;
import com.example.ndkdemotest.R;
import com.sunmi.pay.hardware.aidlv2.AidlConstantsV2;
import com.sunmi.pay.hardware.aidlv2.AidlErrorCodeV2;
import com.sunmi.pay.hardware.aidlv2.readcard.CheckCardCallbackV2;
import com.sunmi.pay.hardware.aidlv2.readcard.ReadCardOptV2;

import java.util.Arrays;
import java.util.Locale;

import sunmi.paylib.SunmiPayKernel;

public class M1Activity extends AppCompatActivity implements View.OnClickListener {

    private SunmiPayKernel mSMPayKernel;

    // 获取读卡模块 初始化一次
    public static ReadCardOptV2 mReadCardOptV2;

    private EditText editResult;

    private String TAG = "ReadCard";
    private String RfCardId = "";

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_card_m1);
        initView();
        connectPayService();
        checkCard();
    }

    /**
     * 1、链接商米支付服务模块 读卡 属于其中一种
     */
    private void connectPayService() {
        mSMPayKernel = SunmiPayKernel.getInstance();
        mSMPayKernel.initPaySDK(this, mConnectCallback);
    }

    private SunmiPayKernel.ConnectCallback mConnectCallback = new SunmiPayKernel.ConnectCallback() {

        @Override
        public void onConnectPaySDK() {
            Log.e(TAG, "onConnectPaySDK");
            try {
                mReadCardOptV2 = mSMPayKernel.mReadCardOptV2;
                checkCard();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onDisconnectPaySDK() {
            Log.e(TAG, "onDisconnectPaySDK");
            showToast(R.string.connect_fail);
        }

    };

    private void initView() {
        editResult = findViewById(R.id.edit_result);
        findViewById(R.id.mb_read).setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        final int id = v.getId();
        switch (id) {
            case R.id.mb_read:
                //readAllSector();
                break;
        }
    }

    /**
     * 2、检卡
     */
    private void checkCard() {
        try {
            mReadCardOptV2.checkCard(AidlConstantsV2.CardType.MIFARE.getValue(), mCheckCardCallback, 60);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private CheckCardCallbackV2 mCheckCardCallback = new CheckCardCallbackV2Wrapper() {

        @Override
        public void findMagCard(Bundle bundle) throws RemoteException {
            Log.e(TAG, "findMagCard");
        }

        @Override
        public void findICCard(String atr) throws RemoteException {
            Log.e(TAG, "findICCard:" + atr);
        }

        @Override
        public void findRFCard(String uuid) throws RemoteException {
            Log.e(TAG, "findRFCard:" + uuid);
            RfCardId = uuid;
            //这里只是回显扫描结果 不必须ui线程执行
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    String s = readAllSector();
                    if ("1".equals(s)) {
                        // 长度不合法
                    }
                    if ("2".equals(s)) {
                        // 卡号不合法
                    }
                    if (s.isEmpty()) {
                        // 没有读到数据
                    }
                }
            });
        }

        @Override
        public void onError(int code, String message) throws RemoteException {
            Log.e(TAG, "error code:" + code + "msg:" + message);
            checkCard();
        }
    };

    /**
     * 3、开始读卡
     */
    private String readAllSector() {
        // 这里需要安装顺序取，读不到就取下一个，一般第一个就能读到
        for (int i = 1; i < 4; i++) {
            String s = readSectorIndex(i);
            if (s.length() == 12) {
                // 根据业务 可以校验一下卡号是否正确
                return s;
            }
        }
        return "";
    }

    /**
     * 读取
     * @param index
     */
    private String readSectorIndex(int index) {
        int startBlockNo = index * 4;

        String str1 = "";
        String str2 = "";
        String str3 = "";

        String result = "";

        if (m1Auth(startBlockNo, ByteUtil.hexStr2Bytes(ReadM1Util.INSTANCE.getKay()))) {
            byte[] outData = new byte[128];
            int res = m1ReadBlock(startBlockNo, outData);
            if (res >= 0 && res <= 16) {
                str1 = ByteUtil.bytes2HexStr(Arrays.copyOf(outData, res));
                Log.e(TAG, "read outData:" + str1);
            } else {
                editResult.setText(R.string.fail);
            }

            outData = new byte[128];
            res = m1ReadBlock(startBlockNo + 1, outData);
            if (res >= 0 && res <= 16) {
                str2 = ByteUtil.bytes2HexStr(Arrays.copyOf(outData, res));
                Log.e(TAG, "read outData:" + str2);
            } else {
                editResult.setText(R.string.fail);
            }

            outData = new byte[128];
            res = m1ReadBlock(startBlockNo + 2, outData);
            if (res >= 0 && res <= 16) {
                str3 = ByteUtil.bytes2HexStr(Arrays.copyOf(outData, res));
                Log.e(TAG, "read outData:" + str3);
            } else {
                editResult.setText(R.string.fail);
            }

            //解密卡号
            result = ReadM1Util.INSTANCE.getCardNo(RfCardId, str1 + str2 + str3, 1);
            showToast("扫描结果：" + result);
            Log.i(TAG, "[扫描结果]:" + result);
            editResult.setText(result);

            //如果需要接着读卡
            //checkCard();
        }

        return result;
    }

    /**
     * 鉴权
     */
    private boolean m1Auth(int block, byte[] keyData) {
        int result = -1;
        try {
            String hexStr = ByteUtil.bytes2HexStr(keyData);
            Log.e(TAG, "block:" + block + " keyBytes:" + hexStr);
            result = mReadCardOptV2.mifareAuth(0, block, keyData);
            Log.e(TAG, "m1Auth result:" + result);
        } catch (RemoteException e) {
            e.printStackTrace();
        }
        if (result == 0) {
            return true;
        }
        String msg = String.format(Locale.getDefault(), "%s:%d(%s)", getString(R.string.card_auth_fail), result, AidlErrorCodeV2.valueOf(result).getMsg());
        Log.e(TAG, "m1Auth msg:" + msg);
//        showToast(msg);
//        checkCard();
        return false;
    }

    /**
     * 读卡
     */
    private int m1ReadBlock(int block, byte[] blockData) {
        try {
            int result = mReadCardOptV2.mifareReadBlock(block, blockData);
            Log.e(TAG, "m1ReadBlock result:" + result);
            return result;
        } catch (RemoteException e) {
            e.printStackTrace();
        }
        return -123;
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        cancelCheckCard();
        if (mSMPayKernel != null) {
            mSMPayKernel.destroyPaySDK();
        }
    }

    private void cancelCheckCard() {
        try {
            mReadCardOptV2.cardOff(AidlConstantsV2.CardType.MIFARE.getValue());
            mReadCardOptV2.cancelCheckCard();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void showToast(String str) {
        Toast.makeText(this, str, Toast.LENGTH_LONG).show();
    }

    private void showToast(int str) {
        Toast.makeText(this, getString(str), Toast.LENGTH_LONG).show();
    }
}
